﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using PSE.Deployment.SetupBase.Configuration;
using PSE.Deployment.SetupBase.Configuration.Actions;
using PSE.Deployment.SetupBase.Configuration.Enums;
using PSE.Deployment.SetupBase.Parameter;
using PSE.Deployment.Util;

namespace PSEComponents.Deployment.SetupGenerator
{
    public class Program
    {
        private static SetupConfiguration config;
        private static SystemInfo _systemInfo;
        private static string _outPutPath;

        public static void Main(string[] args)
        {
            try
            {
                _systemInfo = new SystemInfo();
                _systemInfo.Id = "PSEComponents";
                _systemInfo.Description = "Plataforma de Serviços - Componentes";

                if (args.Length == 0)
                {
                    if (Debugger.IsAttached)
                    {
                        _systemInfo.Version = new PSE.Framework.Common.Version(3, 1, 0, 0);
                        _outPutPath = @"C:\DSEPROJ\Compilados\PSEComponents\Deployment\";
                    }
                    else
                    {
                        throw new Exception("Invalid arguments!");
                    }
                }
                else if (args.Length == 2)
                {
                    _systemInfo.Version = new PSE.Framework.Common.Version(args[0]);
                    _outPutPath = args[1];
                }
                else
                {
                    throw new Exception("Invalid arguments!");
                }

                PopulateConfig();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);
            }
        }

        private static void PopulateConfig()
        {
            config = new SetupConfiguration();

            config.SystemInfo = _systemInfo.Clone();

            config.DefaultInstallPath = @"BMFBOVESPA\";

            PopulateDependencies(config);

            PSE.Deployment.Util.Serializer.Serialize<SetupConfiguration>(config, Path.Combine(_outPutPath, "SetupConfiguration.xml"));

            //SetupParameter p = new SetupParameter();
            //p.SetupConfiguration = config;
            //p.InstalationSource = _outPutPath;
            //p.InstallationPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\" + p.SetupConfiguration.DefaultInstallPath;
            //p.SetupConfiguration.SystemInfo.Groups.SelectDeep(g => g.SubGroups).SelectDeep(g => g.Dependencies).ToList().ForEach(g => { g.Install = true; g.Installed = true; });
            //PSE.Deployment.Util.Serializer.Serialize<SetupParameter>(p, @"C:\Documents and Settings\All Users\Application Data\BMFBOVESPA\PSEComponents\PSEComponentsParameters_v3.xml");
        }

        private static void PopulateDependencies(SetupConfiguration config)
        {
            Group groupClient = new Group();
            groupClient.System = _systemInfo.Clone();
            groupClient.Id = "Client";
            groupClient.Name = "Cliente";
            groupClient.Description = "Cliente";
            groupClient.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Client);
            groupClient.Module.Id = "Common";
            groupClient.Module.Name = "Componentes do Framework";
            groupClient.Index = 1;
            AddActionCopy(groupClient, "Copia dos arquivos da plataforma de serviços", @"Settings\");
            AddCreateShortcut(groupClient, "Criação dos atalhos", null);
            AddActionUpdateWindowsRegistry(groupClient, "Criação do registro de windows");
            AddActionUpdateConfig(groupClient);

            ((Copy)groupClient.Actions[0]).Folders.Add(new FolderInfo()
            {
                Source = @"Bin\PSEComponents\",
                Destination = @"PSEComponents\",
                Files = new List<string> { "GeneralSettings.config" }
            });

            Group groupServer = new Group();
            groupServer.System = _systemInfo.Clone();
            groupServer.Id = "Server";
            groupServer.Name = "Servidor";
            groupServer.Description = "Servidor";
            groupServer.Module.Id = "Common";
            groupServer.Module.Name = "Componentes do Framework";
            groupServer.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Server);
            groupServer.Index = 2;
            AddActionCopy(groupServer, "Copia dos arquivos da plataforma de serviços", @"Settings\");
            AddCreateShortcut(groupServer, "Criação dos atalhos", null);
            AddActionUpdateWindowsRegistry(groupServer, "Criação do registro de windows");

            ((Copy)groupServer.Actions[0]).Folders.Add(new FolderInfo()
            {
                Source = @"Bin\PSEComponents\",
                Destination = @"PSEComponents\",
                Files = new List<string> { "GeneralSettings.config" }
            });

            Group groupDependencyPmPSEClient = new Group();
            groupDependencyPmPSEClient.System = _systemInfo.Clone();
            groupDependencyPmPSEClient.Id = "PSEComponents-ProcessManager-Client";
            groupDependencyPmPSEClient.Name = "Cliente do Gerenciador de Processos";
            groupDependencyPmPSEClient.Description = "Cliente do Gerenciador de Processos da plataforma de serviços";
            groupDependencyPmPSEClient.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Client);
            groupDependencyPmPSEClient.Module.Id = "GP";
            groupDependencyPmPSEClient.Module.Name = "Gerenciador de Processos";
            groupDependencyPmPSEClient.Index = 0;
            AddActionCopy(groupDependencyPmPSEClient, "Copia dos arquivos do gerenciador de processos da plataforma de serviços", @"ProcessManager\Client\", @"ProcessManager\Data\", @"ProcessManager\Common\", @"ProcessManager\Management\", @"ProcessManager\ServiceManager\", @"LogPackager\Application\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddActionInstallAssembly(groupDependencyPmPSEClient, "Instalação dos arquivos do gerenciador de processos da plataforma de serviços", @"ProcessManager\Client\", @"ProcessManager\Data\", @"ProcessManager\Common\", @"ProcessManager\Management\", @"LogPackager\Application\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddCreateShortcut(groupDependencyPmPSEClient, "Criação dos atalhos", new object[] { @"ProcessManager\ServiceManager\", "ServiceManager.exe", @"ProcessManager\ServiceManager\", "ServiceManager.ico", @"Plataforma de Serviços\Componentes\", "Process Manager.lnk", new List<PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder>() { PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder.StartMenu } });
            groupClient.AddSubGroup(groupDependencyPmPSEClient);

            Group groupDependencyPmPSEServer = new Group();
            groupDependencyPmPSEServer.System = _systemInfo.Clone();
            groupDependencyPmPSEServer.Id = "PSEComponents-ProcessManager-Server";
            groupDependencyPmPSEServer.Name = "Servidor do Gerenciador de Processos";
            groupDependencyPmPSEServer.Description = "Servidor do Gerenciador de Processos da plataforma de serviços";
            groupDependencyPmPSEServer.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Server);
            groupDependencyPmPSEServer.Module.Id = "GP";
            groupDependencyPmPSEServer.Module.Name = "Gerenciador de Processos";
            groupDependencyPmPSEServer.Index = 0;
            AddActionCopy(groupDependencyPmPSEServer, "Copia dos arquivos do gerenciador de processos da plataforma de serviços", @"ProcessManager\Common\", @"ProcessManager\Data\", @"ProcessManager\Server\", @"LogPackager\Service\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddActionUpdateConfigProcessManagerServer(groupDependencyPmPSEServer, @"ProcessManager\Server\");
            AddActionInstallAssembly(groupDependencyPmPSEServer, "Instalação dos arquivos do gerenciador de processos da plataforma de serviços", @"ProcessManager\Common\", @"ProcessManager\Data\", @"ProcessManager\Server\", @"LogPackager\Service\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddActionInstallWindowsService(groupDependencyPmPSEServer, "Instalação do serviço do gerenciador de processos da plataforma de serviços",
                new string[] { "PSEProcessManager", "BM&FBOVESPA Process Manager", "Instalação do serviço do gerenciador de processos da plataforma de serviços", @"ProcessManager\Server\", @"InteligenceManager.exe", @"InteligenceManager.exe.config", "true" });
            groupServer.AddSubGroup(groupDependencyPmPSEServer);

            Group groupDependencyComPSE = new Group();
            groupDependencyComPSE.System = _systemInfo.Clone();
            groupDependencyComPSE.Id = "PSEComponents-Communication";
            groupDependencyComPSE.Name = "Camada de Comunicação";
            groupDependencyComPSE.Description = "Camada de Comunicação da plataforma de serviços";
            groupDependencyComPSE.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Server);
            groupDependencyComPSE.Module.Id = "COM";
            groupDependencyComPSE.Module.Name = "Camada de Comunicação";
            groupDependencyComPSE.Index = 0;
            AddActionCopy(groupDependencyComPSE, "Copia dos arquivos da Camada de comunicação da plataforma de serviços", @"Communication\");
            AddActionInstallAssembly(groupDependencyComPSE, "Instalação dos arquivos da Camada de comunicação da plataforma de serviços", @"Communication\");
            AddActionUpdateConfigCommunication(groupDependencyComPSE);
            AddActionInstallWindowsService(groupDependencyComPSE, "Instalação do serviço do Fix Proxy da plataforma de serviços",
                new string[] { "BM&FBOVESPA Fix Communication", "BM&FBOVESPA Fix Communication", "Instalação do serviço do Fix Proxy da plataforma de serviços", @"Communication\Fix\", "FixProxy.exe", @"FixProxy.exe.config", "false" });
            groupServer.AddDependency(groupDependencyComPSE);

            Group groupDependencyHosterPSEClient = new Group();
            groupDependencyHosterPSEClient.System = _systemInfo.Clone();
            groupDependencyHosterPSEClient.Id = "PSEComponents-Hoster-Client";
            groupDependencyHosterPSEClient.Name = "Cliente do Hoster";
            groupDependencyHosterPSEClient.Description = "Cliente do Serviço de Hospedagem da plataforma de serviços";
            groupDependencyHosterPSEClient.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Client);
            groupDependencyHosterPSEClient.Module.Id = "HT";
            groupDependencyHosterPSEClient.Module.Name = "Hoster";
            groupDependencyHosterPSEClient.Index = 0;
            AddActionCopy(groupDependencyHosterPSEClient, "Copia dos arquivos do cliente do Hoster da plataforma de serviços", @"Hosting\", @"LogPackager\Application\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddActionInstallAssembly(groupDependencyHosterPSEClient, "Instalação dos arquivos do cliente do Hoster da plataforma de serviços", @"LogPackager\Application\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddCreateShortcut(groupDependencyHosterPSEClient, "Criação dos atalhos", new object[] { @"Hosting\", "HosterManager.exe", @"Hosting\", "Hosting.ico", @"Plataforma de Serviços\Componentes\", "WCF Services Hoster Manager.lnk", new List<PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder>() { PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder.Desktop, PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder.StartMenu } });
            groupClient.AddSubGroup(groupDependencyHosterPSEClient);

            Group groupDependencyHosterPSEServer = new Group();
            groupDependencyHosterPSEServer.System = _systemInfo.Clone();
            groupDependencyHosterPSEServer.Id = "PSEComponents-Hoster";
            groupDependencyHosterPSEServer.Name = "Servidor do Hoster";
            groupDependencyHosterPSEServer.Description = "Serviço de Hospedagem da plataforma de serviços";
            groupDependencyHosterPSEServer.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Server);
            groupDependencyHosterPSEServer.Module.Id = "HT";
            groupDependencyHosterPSEServer.Module.Name = "Hoster";
            groupDependencyHosterPSEServer.Index = 0;
            AddActionCopy(groupDependencyHosterPSEServer, "Copia dos arquivos do Hoster da plataforma de serviços", @"Hosting\", @"LogPackager\Service\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddActionInstallAssembly(groupDependencyHosterPSEServer, "Instalação dos arquivos do Hoster da plataforma de serviços", @"LogPackager\Service\", @"LogPackager\Common\", @"LogPackager\PSE.LogPackager.dll");
            AddActionInstallWindowsService(groupDependencyHosterPSEServer, "Instalação do serviço do Hoster da plataforma de serviços",
                new string[] { "PSEServiceHoster", "BM&FBOVESPA WCF Services Hoster", "Instalação do serviço do Hoster da plataforma de serviços", @"Hosting\", "ServiceHoster.exe", @"ServiceHoster.exe.config", "true" });
            //AddActionInstallWcfServiceMain(groupDependencyLogPackagerPSEServer, "Instalação do site principal do sistema");
            AddActionInstallWcfService(groupDependencyHosterPSEServer, "LogPackager", "/PSEComponents/LogPackager/Service", "Instalação dos serviços do Coletor de evidências", @"LogPackager\Service\");
            groupServer.AddSubGroup(groupDependencyHosterPSEServer);

            Group groupDependencyUpdaterPSEClient = new Group();
            groupDependencyUpdaterPSEClient.System = _systemInfo.Clone();
            groupDependencyUpdaterPSEClient.Id = "PSEComponents-Updater-Client";
            groupDependencyUpdaterPSEClient.Name = "Cliente do Atualizador";
            groupDependencyUpdaterPSEClient.Description = "Cliente de Atualização da plataforma de serviços";
            groupDependencyUpdaterPSEClient.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Client);
            groupDependencyUpdaterPSEClient.Module.Id = "UP";
            groupDependencyUpdaterPSEClient.Module.Name = "Atualizador de Versões";
            groupDependencyUpdaterPSEClient.Index = 0;
            AddActionCopy(groupDependencyUpdaterPSEClient, "Copia dos arquivos do serviço de Atualização da plataforma de serviços", @"Updater\");
            AddActionInstallAssembly(groupDependencyUpdaterPSEClient, "Instalação dos arquivos do serviço de Atualização da plataforma de serviços", @"Updater\");
            AddActionInstallWindowsService(groupDependencyUpdaterPSEClient, "Instalação do serviço de Atualização da plataforma de serviços",
                new string[] { "PSEMonitorUpdateService", "BM&FBOVESPA Monitor Update Service", "Instalação do serviço de Atualização da plataforma de serviços", @"Updater\", @"UpdaterMonitor.exe", @"UpdaterMonitor.exe.config", "true" });
            groupClient.AddSubGroup(groupDependencyUpdaterPSEClient);

            Group groupDependencyUpdaterPSEServer = new Group();
            groupDependencyUpdaterPSEServer.System = _systemInfo.Clone();
            groupDependencyUpdaterPSEServer.Id = "PSEComponents-Updater-Server";
            groupDependencyUpdaterPSEServer.Name = "Servidor do Atualizador";
            groupDependencyUpdaterPSEServer.Description = "Servidor de Atualização da plataforma de serviços";
            groupDependencyUpdaterPSEServer.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Server);
            groupDependencyUpdaterPSEServer.Module.Id = "UP";
            groupDependencyUpdaterPSEServer.Module.Name = "Atualizador de Versões";
            groupDependencyUpdaterPSEServer.Index = 0;
            AddActionCopy(groupDependencyUpdaterPSEServer, "Copia dos arquivos do serviço de Atualização da plataforma de serviços", @"Updater\");
            AddActionInstallAssembly(groupDependencyUpdaterPSEServer, "Instalação dos arquivos do serviço de Atualização da plataforma de serviços", @"Updater\");
            AddActionInstallWindowsService(groupDependencyUpdaterPSEServer, "Instalação do serviço de Atualização da plataforma de serviços",
                new string[] { "PSEUpdateService", "BM&FBOVESPA Update Service", "Instalação do serviço de Atualização da plataforma de serviços", @"Updater\", @"UpdaterServer.exe", @"UpdaterServer.exe.config", "true" });
            groupServer.AddSubGroup(groupDependencyUpdaterPSEServer);

            Group groupDependencyVersionsPSEClient = new Group();
            groupDependencyVersionsPSEClient.System = _systemInfo.Clone();
            groupDependencyVersionsPSEClient.Id = "PSEComponents-Versions-Client";
            groupDependencyVersionsPSEClient.Name = "Cliente do Verificador de Versões";
            groupDependencyVersionsPSEClient.Description = "Cliente do Verificador de Versões da plataforma de serviços";
            groupDependencyVersionsPSEClient.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Client);
            groupDependencyVersionsPSEClient.Module.Id = "VER";
            groupDependencyVersionsPSEClient.Module.Name = "Verificador de Versões";
            groupDependencyVersionsPSEClient.Index = 0;
            AddActionCopy(groupDependencyVersionsPSEClient, "Copia dos arquivos do serviço de verificação de Versões da plataforma de serviços", @"Versions\");
            AddActionInstallAssembly(groupDependencyVersionsPSEClient, "Instalação dos arquivos do serviço de verificação de Versões da plataforma de serviços", @"Versions\");
            groupClient.AddDependency(groupDependencyVersionsPSEClient);

            Group groupDependencyVersionsPSEServer = new Group();
            groupDependencyVersionsPSEServer.System = _systemInfo.Clone();
            groupDependencyVersionsPSEServer.Id = "PSEComponents-Versions-Server";
            groupDependencyVersionsPSEServer.Name = "Servidor do Verificador de Versões";
            groupDependencyVersionsPSEServer.Description = "Servidor de verificação de Versões da plataforma de serviços";
            groupDependencyVersionsPSEServer.Layers.Add(PSE.Deployment.SetupBase.Configuration.Enums.Layer.Server);
            groupDependencyVersionsPSEServer.Module.Id = "VER";
            groupDependencyVersionsPSEServer.Module.Name = "Verificador de Versões";
            groupDependencyVersionsPSEServer.Index = 0;
            AddActionCopy(groupDependencyVersionsPSEServer, "Copia dos arquivos do serviço de verificação de Versões da plataforma de serviços", @"Versions\");
            AddActionInstallAssembly(groupDependencyVersionsPSEServer, "Instalação dos arquivos do serviço de verificação de Versões da plataforma de serviços", @"Versions\");
            AddActionInstallWcfService(groupDependencyVersionsPSEServer, "Versions", "/PSEComponents/Versions/Service", "Instalação dos serviços do Visualizador de Versões", @"Versions\Service\");
            groupServer.AddDependency(groupDependencyVersionsPSEServer);

            config.SystemInfo.Groups.Add(groupClient);
            config.SystemInfo.Groups.Add(groupServer);
        }

        private static void AddActionCopy(Group group, string description, params string[] destinations)
        {
            Copy c = new Copy();
            c.Id = "Copy-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 0;

            foreach (string destination in destinations)
            {
                if (!Path.HasExtension(destination))
                {
                    c.Folders.Add(new FolderInfo()
                    {
                        Source = @"Bin\" + group.System.Id + @"\" + destination,
                        Destination = group.System.Id + @"\" + destination,
                    });
                }
                else
                {
                    c.Folders.Add(new FolderInfo()
                    {
                        Source = @"Bin\" + group.System.Id + @"\" + Path.GetDirectoryName(destination)+ @"\",
                        Destination = group.System.Id + @"\" + Path.GetDirectoryName(destination)+ @"\",
                        Files = new List<string> { Path.GetFileName(destination) }
                    });
                }
            }

            group.Actions.Add(c);
        }

        private static void AddActionInstallWcfServiceMain(Group group, string description)
        {
            InstallWcfServiceMain c = new InstallWcfServiceMain();
            c.Id = "InstallWcfServiceMain-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 3;
            c.HttpPort = 803;
            c.TcpPort = 810;
            c.Folder = new FolderInfo() { Source = @"Bin\PSEComponents\", Destination = @"PSEComponents\" };

            group.Actions.Add(c);
        }

        private static void AddActionInstallWcfService(Group group, string processName, string path, string description, params string[] destinations)
        {
            InstallWcfService c = new InstallWcfService();
            c.Id = "InstallWcfService-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 20;

            foreach (string destination in destinations)
            {
                c.Services.Add(new PSE.Deployment.SetupBase.Configuration.WcfService()
                {
                    ProcessName = processName,
                    Path = path,
                    ServerName = "localhost",
                    Folder = new FolderInfo()
                    {
                        Source = @"Bin\" + group.System.Id + @"\" + destination,
                        Destination = group.System.Id + @"\" + destination,
                    }
                });
            }

            group.Actions.Add(c);
        }

        private static void AddActionInstallAssembly(Group group, string description, params string[] destinations)
        {
            InstallAssembly c = new InstallAssembly();
            c.Id = "InstallAssembly-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 1;
    
            foreach (string destination in destinations)
            {
                if (!Path.HasExtension(destination))
                {
                    c.Folders.Add(new FolderInfo()
                    {
                        Source = @"Bin\" + group.System.Id + @"\" + destination,
                        Destination = group.System.Id + @"\" + destination,
                    });
                }
                else
                {
                    c.Folders.Add(new FolderInfo()
                    {
                        Source = @"Bin\" + group.System.Id + @"\" + Path.GetDirectoryName(destination) + @"\",
                        Destination = group.System.Id + @"\" + Path.GetDirectoryName(destination) + @"\",
                        Files = new List<string> { Path.GetFileName(destination) }
                    });
                }
            }
            
            group.Actions.Add(c);
        }

        private static void AddActionInstallWindowsService(Group group, string description, params string[][] services)
        {
            InstallWindowsService c = new InstallWindowsService();
            c.Id = "InstallWindowsService-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 30;

            foreach (string[] service in services)
            {
                c.Services.Add(new PSE.Deployment.SetupBase.Configuration.WindowsService()
                {
                    ServiceName = service[0],
                    DisplayName = service[1],
                    Description = service[2],
                    ServiceFile = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Source = @"Bin\" + group.System.Id + @"\" + service[3],
                        Destination = group.System.Id + @"\" + service[3],
                        FileName = service[4],
                    },
                    ConfigFile = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Source = @"Bin\" + group.System.Id + @"\" + service[3],
                        Destination = group.System.Id + @"\" + service[3],
                        FileName = service[4],
                    },
                    Start = Convert.ToBoolean(service[6])
                });
            }

            group.Actions.Add(c);
        }

        private static void AddActionInstallPSECertificate(Group group, string description)
        {
            InstallCertificate c = new InstallCertificate();
            c.Id = "InstallCertificate-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 2;

            c.Certificates.Add(new PSE.Deployment.SetupBase.Configuration.Certificate()
            {
                StoreName = System.Security.Cryptography.X509Certificates.StoreName.AuthRoot,
                Password = "A5MKUVMFnmKAZsTnKvFG9yXcx4y/Eet6",
                File = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                {
                    Source = @"Bin\PSE\Certificates\",
                    Destination = @"PSE\Certificates\",
                    FileName = "BVMFPSERootCA.pfx"
                }
            });

            group.Actions.Add(c);
        }

        private static void AddCreateShortcut(Group group, string description, params object[][] destinations)
        {
            CreateShortcut c = new CreateShortcut();
            c.Id = "CreateShortcut-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 10;

            if (group.Id == "Client" || group.Id == "Server")
            {
                c.Shortcuts.Add(new Shortcut()
                {
                    Executable = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"PSEComponents\Setup-v3\",
                        FileName = "PSEComponentsConfigurationManager.exe",
                    },
                    Icon = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"PSEComponents\Setup-v3\",
                        FileName = "PSEComponents.ico",
                    },
                    ShotcutFile = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"Plataforma de Serviços\Componentes\",
                        FileName = "Configurador dos componentes.lnk",
                    },
                    SpecialFolders = new List<PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder>() { PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder.Desktop, PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder.StartMenu }
                });

                c.Shortcuts.Add(new Shortcut()
                {
                    Executable = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"PSEComponents\Versions\",
                        FileName = "PSEComponentsVersions.exe",
                        Arguments = "3"
                    },
                    Icon = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"PSEComponents\Versions\",
                        FileName = "Versions.ico",
                    },
                    ShotcutFile = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"Plataforma de Serviços\Componentes\",
                        FileName = "Visualizador de Versões PSEComponents.lnk",
                    },
                    SpecialFolders = new List<PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder>() { PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder.StartMenu }
                });

                c.Shortcuts.Add(new Shortcut()
                {
                    Executable = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"PSEComponents\Setup-v3\",
                        FileName = "SetupUninstall.exe",
                    },
                    Icon = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"PSEComponents\Setup-v3\",
                        FileName = "PSEComponents.ico",
                    },
                    ShotcutFile = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                    {
                        Destination = @"Plataforma de Serviços\Componentes\",
                        FileName = "Setup.lnk",
                    },
                    SpecialFolders = new List<PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder>() { PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder.StartMenu }
                });
            }
            else
            {
                foreach (object[] destination in destinations)
                {
                    c.Shortcuts.Add(new Shortcut()
                    {
                        Executable = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                        {
                            Source = @"Bin\" + group.System.Id + @"\" + destination[0],
                            Destination = group.System.Id + @"\" + destination[0],
                            FileName = destination[1].ToString(),
                        },
                        Icon = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                        {
                            Source = @"Bin\" + group.System.Id + @"\" + destination[2],
                            Destination = group.System.Id + @"\" + destination[2],
                            FileName = destination[3].ToString(),
                        },
                        ShotcutFile = new PSE.Deployment.SetupBase.Configuration.FileInfo()
                        {
                            Destination = destination[4].ToString(),
                            FileName = destination[5].ToString(),
                        },
                        SpecialFolders = (List<PSE.Deployment.SetupBase.Configuration.Enums.SpecialFolder>)destination[6]
                    });
                }
            }

            group.Actions.Add(c);
        }

        private static void AddActionUpdateConfigProcessManagerServer(Group group, string folder)
        {
            UpdateConfig c = new UpdateConfig();
            c.Id = "UpdateConfig-" + group.Id;
            c.Description = "Atualizaçao de config";
            c.GroupId = group.Id;
            c.Index = 15;

            XmlFile xmlFile = new XmlFile()
            {
                Description = "Configuração dos servidor do gerenciador de processos",
                Title = "Processos",
                Folder = new FolderInfo()
                {
                    Source = group.System.Id + folder,
                    Destination = group.System.Id + folder,
                }
            };

            #region appSettings

            xmlFile.Tags.Add(new XmlTag()
            {
                Description = "FolderProcessPath",
                Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.CombineRootPath,
                IsVisible = false,
                Value = @"Processos\",
                XPathList = new List<XmlXPath> { new XmlXPath { XPath = "/configuration/appSettings/add[@key='FolderProcessPath']/@value" } }
            });

            xmlFile.Tags.Add(new XmlTag()
            {
                Description = "InteligenceModuleFolderPath",
                Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.CombineRootPath,
                IsVisible = false,
                Value = @"ProcessManager\Server",
                XPathList = new List<XmlXPath> { new XmlXPath { XPath = "/configuration/appSettings/add[@key='InteligenceModuleFolderPath']/@value" } }
            });

            xmlFile.Tags.Add(new XmlTag()
            {
                Description = "ExecutorPath",
                Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.CombineRootPath,
                IsVisible = false,
                Value = @"ProcessManager\Server\PSE.ProcessManager.Server.Process.Executor.exe",
                XPathList = new List<XmlXPath> { new XmlXPath { XPath = "/configuration/appSettings/add[@key='ExecutorPath']/@value" } }
            });

            #endregion

            c.XmlFiles = new List<XmlFile>();
            c.XmlFiles.Add(xmlFile);

            group.Actions.Add(c);
        }

        private static void AddActionUpdateConfigCommunication(Group group)
        {
            UpdateConfig c = new UpdateConfig();
            c.Id = "UpdateConfig-" + group.Id;
            c.Description = "Atualizaçao de config";
            c.GroupId = group.Id;
            c.Index = 15;

            XmlFile xmlFile = new XmlFile()
            {
                Description = "Configuração das sessões FIX",
                Title = "Configuração das sessões FIX",
                Folder = new FolderInfo()
                {
                    Source = @"Bin\" + group.System.Id + @"\" + @"Communication\Fix\",
                    Destination = group.System.Id + @"\" + @"Communication\Fix\",
                }
            };

            xmlFile.Tags.Add(
            new XmlTag()
            {
                XPathList = new List<XmlXPath> { new XmlXPath { XPath = "/configuration/fixConfiguration/fixSessions" } },
                Name = "session",
                Description = "Sessões FIX",
                OperationType = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagOperationType.Insert,
                Attributes = new List<XmlAttribute>()
				{
					new XmlAttribute()
					{
						Name = "name",
						Description = "Nome da sessão",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.String
					},
					new XmlAttribute()
					{
						Name = "brokerage",
						Description = "Código da Corretora na BM&F",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.String
					},
                    new XmlAttribute()
					{
						Name = "senderCompID",
						Description = "Usuário",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.String
					},
					new XmlAttribute()
					{
						Name = "password",
						Description = "Senha",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Password,
						IsEncrypted = true,
						EncryptionAlgorithm = PSE.Deployment.SetupBase.Configuration.Enums.CryptographyAlgorithm.DES_Generic
					},					
					new XmlAttribute()
					{
						Name = "targetCompID",
						Description = "TargetCompID",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.String
					},
					new XmlAttribute()
					{
						Name = "socketConnectHost",
						Description = "Servidor",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.String
					},
					new XmlAttribute()
					{
						Name = "socketConnectPort",
						Description = "Porta",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.String
					},
					new XmlAttribute()
					{
						Name = "startTime",
						Description = "Hora de ínicio da sessão",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Time
					},
					new XmlAttribute()
					{
						Name = "endTime",
						Description = "Hora fim da sessão",
						Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Time
					}
				}
            });

            c.XmlFiles = new List<XmlFile>();
            c.XmlFiles.Add(xmlFile);

            group.Actions.Add(c);
        }

        private static void AddActionUpdateConfig(Group group)
        {
            UpdateConfig c = new UpdateConfig();
            c.Id = "UpdateConfig-" + group.Id;
            c.Description = "Atualizaçao de config";
            c.GroupId = group.Id;
            c.Index = 15;

            XmlFile xmlFile = new XmlFile()
            {
                Description = "Configuração da estação",
                Title = "Geral",
                Folder = new FolderInfo()
                {
                    Source = @"Bin\" + group.System.Id + @"\",
                    Destination = group.System.Id + @"\",
                    Files = new List<string>() { "GeneralSettings.config" }
                }
            };

            #region appSettings

            xmlFile.Tags.Add(new XmlTag()
            {
                Description = "Servidor de Atualização do Atualizador Automático",
                Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Endpoint,
                IsVisible = true,
                Value = "localhost",
                XPathList = new List<XmlXPath> { new XmlXPath { XPath = "/configuration/applicationConfiguration/updateConfiguration/@defaultUpdateServerUrl" } }
            });

            xmlFile.Tags.Add(new XmlTag()
            {
                Description = "Servidor do Gerenciador de Processos",
                Type = PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Endpoint,
                Value = "localhost",
                XPathList = new List<XmlXPath> { new XmlXPath { XPath = "/configuration/applicationConfiguration/inteligenceManagerConfiguration/@inteligenceManagerAddress" } }
            });

            #endregion

            c.XmlFiles = new List<XmlFile>();
            c.XmlFiles.Add(xmlFile);

            group.Actions.Add(c);
        }

        private static void AddActionUpdateWindowsRegistry(Group group, string description)
        {
            UpdateWindowsRegistry c = new UpdateWindowsRegistry();
            c.Id = "UpdateWindowsRegistry-" + group.Id;
            c.Description = description;
            c.GroupId = group.Id;
            c.Index = 10;

            c.Keys.Add(new RegistryKey()
            {
                Name = @"SOFTWARE\PSEComponents",
                Values = new List<RegistryValue>() 
                { 
                    new RegistryValue() { Name = "ApplicationRootDirectory", Description="ApplicationRootDirectory", XPath = "/SetupParameter/@FullInstallationPath", RegistryValueKind = Microsoft.Win32.RegistryValueKind.String , IsVisible = false, Type = XmlTagType.String }
                }
            });

            c.Keys.Add(new RegistryKey()
            {
                Name = @"SOFTWARE\PSEComponents",
                Values = new List<RegistryValue>() 
                { 
                    new RegistryValue() { Name = "SystemDescription", Description="SystemDescription", Value = "PSE Components", RegistryValueKind = Microsoft.Win32.RegistryValueKind.String , IsVisible = false, Type = XmlTagType.String }
                }
            });

            group.Actions.Add(c);
        }
    }
}
